package com.game.raceroom
{
	import com.game.chat.ChatCanvas;
	import com.game.main.MainCanvas;
	import com.game.raceroom.ContDownCanvas;
	import com.game.raceroom.MapCanvas;
	import com.game.raceroom.SkillBarCanvas;
	import com.game.raceroom.TimerCanvas;
	import com.game.raceroom.UserStatusCanvas;
	import com.game.raceroom.events.GameEvent;
	import com.game.raceroom.events.GameEventDispatcher;
	import com.game.raceroom.loader.ItemLoader;
	import com.game.raceroom.player.CarInfo;
	import com.game.raceroom.player.MapInfo;
	import com.game.raceroom.player.Player;
	import com.game.raceroom.player.UserInfo;
	import com.game.raceroom.player.contrl.ActorContrl;
	import com.game.raceroom.player.contrl.KeyboardContrl;
	import com.game.raceroom.player.contrl.MapContrl;
	import com.game.raceroom.player.effect.ActionChecker;
	import com.game.raceroom.player.effect.Effect;
	import com.game.raceroom.player.skill.Skill;
	import com.net.NetTrans;
	import com.util.DEF;
	import com.util.HashMap;
	import com.util.Vector;
	
	import flash.display.Stage;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.net.NetConnection;
	import flash.net.Responder;
	import flash.utils.ByteArray;
	import flash.utils.clearInterval;
	import flash.utils.getTimer;
	import flash.utils.setInterval;
	
	import mx.containers.Canvas;
	import mx.controls.Alert;
	import mx.core.UIComponent;
	
	
	public class Room
	{
		public var userId:int;
		public var gameCanvas:Canvas;
		public var mapContrl:MapContrl;
		public var actorContrl:ActorContrl;
		public var keyContrl:KeyboardContrl;
		public var bgCanvas:UIComponent=new UIComponent;
		public var acCanvas:UIComponent=new UIComponent;
		public var fgCanvas:UIComponent=new UIComponent;
		public var topCanvas:UIComponent=new UIComponent;
		public var firstCanvas:UIComponent=new UIComponent;
		
		public var players:HashMap=new HashMap;
		public var effects:Vector=new Vector();
		public var actorInfo:UserInfo;
		public var mapInfo:MapInfo;
		public var stage:Stage;
		public var chat:ChatCanvas;
		public var _parents:Object;
		public var events:GameEventDispatcher;
		
		public var mync:NetConnection;
		public var ac:ActionChecker;
		public var timer:TimerCanvas=new TimerCanvas;
		public var cont:ContDownCanvas=new ContDownCanvas;
		 public var userStatus:UserStatusCanvas=new UserStatusCanvas;
		 public var skillBar:SkillBarCanvas=new SkillBarCanvas;
		 public var roomid:int;
		 public var mode:int;
 
		 
        public var map:MapCanvas=new MapCanvas;
		public function Room(id:int,GC:Canvas,stage:Stage,chat:ChatCanvas,_parents:Object)
		{
			cont.room=this;
			NetTrans.setRaceRoom(this);
			this.roomid=id;
			this._parents=_parents;
			events = new GameEventDispatcher();
			this.chat=chat;
			gameCanvas=GC;
		    gameCanvas.setFocus();
		    gameCanvas.addEventListener(MouseEvent.CLICK,setFocus1);
			this.stage=stage;
 
			
			bgCanvas.x=DEF.GAME_CANVAS_X;
			bgCanvas.y=DEF.GAME_CANVAS_Y;
			bgCanvas.width=DEF.GAME_CANVAS_WIDTH;
			bgCanvas.height=DEF.GAME_CANVAS_HEIGHT;
			acCanvas.x=DEF.GAME_CANVAS_X;
			acCanvas.y=DEF.GAME_CANVAS_Y;
			acCanvas.width=DEF.GAME_CANVAS_WIDTH;
			acCanvas.height=DEF.GAME_CANVAS_HEIGHT;
			topCanvas.x=DEF.GAME_CANVAS_X;
			topCanvas.y=DEF.GAME_CANVAS_Y;
			topCanvas.width=DEF.GAME_CANVAS_WIDTH;
			topCanvas.height=DEF.GAME_CANVAS_HEIGHT;
			
			fgCanvas.x=DEF.GAME_CANVAS_X;
			fgCanvas.y=DEF.GAME_CANVAS_Y;
			fgCanvas.width=DEF.GAME_CANVAS_WIDTH;
			fgCanvas.height=DEF.GAME_CANVAS_HEIGHT;
			
               acCanvas.visible=false;
               bgCanvas.visible=false;
               topCanvas.visible=false;
               fgCanvas.visible=false;
			gameCanvas.addChild(bgCanvas);
			
			gameCanvas.addChild(acCanvas);
			gameCanvas.addChild(fgCanvas);
			gameCanvas.addChild(topCanvas);
			timer.x=(DEF.GAME_CANVAS_WIDTH-timer.width)/2;
			timer.y=20;
			cont.x=(DEF.GAME_CANVAS_WIDTH-cont.width)/2;
			cont.y=(DEF.GAME_CANVAS_HEIGHT-cont.height)/2-40;
			topCanvas.addChild(timer);
			topCanvas.addChild(cont);
			skillBar.x=428;
			skillBar.y=472;
			map.x=623;
			map.y=5;
			
			 topCanvas.addChild(userStatus);
			 topCanvas.addChild(skillBar);
			 topCanvas.addChild(map);

			events.addEventListener(GameEventDispatcher.ON_ACTION,onAction);
			events.addEventListener(GameEventDispatcher.ON_SKILL,onSkill);
			//initWorld();
		}
		public function startRacing():void{
			if(!isRunning){
				 isRunning=true;
				 run_id=setInterval(run,DEF.FRAME_RATE);
   			} 		
		}
		public function stopRacing():void{
			if(isRunning){
			   isRunning=false;
			   clearInterval(run_id);
			}  
		}
		public static var gameStatus:int=0;
		public static var GAME_STATUS_WAITTING:int=0;
		public static var GAME_STATUS_INITMAP:int=1;
		public static var GAME_STATUS_INITPLAYER:int=2;
		public static var GAME_STATUS_WAITSTART:int=3;
		public static var GAME_STATUS_START:int=4;
	    public function run():void{
            map.update();
        	if(started){
        		currentSystemTime=getTimer();
        		checkKeyboardDirInput();
	        	this.refreshTimer();
	        	
	        	updatePlayers();
	        	mapContrl.updateMap();
	        	showPlayers();
	        	//locked=false;
	        	checkEffects();
	        	skillBar.updateSkills();
        	}
        	//checkCrash();
        }
        public var lastInputTime:Number=0;
        public var inputTime:Number=0;
        public function checkKeyboardDirInput():void{
        	inputTime=currentSystemTime;
        	if(actorContrl.keyInput.size()<=0)return;
        	//trace(inputTime+"   "+lastInputTime);
        	if(inputTime-lastInputTime<50){
        		
        		return;
        	}
        	
        	lastInputTime=currentSystemTime;
        	var code:int=actorContrl.action.getCurentActionCode();
        	for(var i:int=0;i<actorContrl.keyInput.size();i++){
        		actorContrl.action.setKeyCode((int)(actorContrl.keyInput.getObjById(i)));
        	}
        	actorContrl.keyInput.reset();
        	if(code==actorContrl.action.getCurentActionCode()){
        		return;
        	}
        	sendAction(); 
        } 
        public var taskList:Vector=new Vector;
        public var task_id:int=0;
        public function addTesk(cmd:Array):void{
        	taskList.put(cmd);
        }
//        public function checkTesk():void{
//        	//trace("checkCmd  start ");
//        	 
//        	if(taskList.size()>0){
//	        	var dataPacks:Array=taskList.toArray();
//	        	taskList.reset();
//	        	var parseData:* = parseDataPack;
//	        	for(var i in dataPacks){
//	        		var dataPack:Array=(Array)(dataPacks[i].value);
//	        		parseData(dataPack[0]);
//	        	}
//        	}
//        }
		
		private static var sendcmd_otherStartGame:int=0;
		private var sendcmd_otherMoveAction:int=1;
		private var sendcmd_otherActionAction:int=2;
		private var sendcmd_ActionsPack:int=3;
		private var sendcmd_receiveGameScore:int=4;
		
		private var sendcmd_initPlayers:int=5;
		private var sendcmd_startGame:int=6;
		private var sendcmd_gameOver:int=7;
		private var sendcmd_initStock:int=8;
		private var sendcmd_fixPosition:int=9;

        
 

		public function setFocus1(e:Event):void
		{
			gameCanvas.setFocus();
		}
		public function setActorInfo(info:UserInfo):void
		{
			this.actorInfo = info;	
			userStatus.setUserInfo(this.actorInfo);
		}
		public function setMapInfo(info:MapInfo):void
		{
			this.mapInfo = info;	
		}	
		 public var waitingAction:Boolean=false;
		 public var actions:Vector=new Vector;	
		 public var skills:Vector=new Vector;	
		 public var sendActions:Array=new Array;	
		 public var tempSkill:int=-1;
 		public function onAction(e:GameEvent):void
		{
        	
        	 actorContrl.action.composeKeyCode(actions,actorContrl.keyCode);
        	if(!started)return;
        	//if(waitingAction)return;
        	//waitingAction=true;
        	//actionCopy();
        	sendAction();
		} 
 		public function onSkill(e:GameEvent):void
		{
        	if(!started)return;
        	//if(waitingAction)return;
        	//waitingAction=true;
        	sendSkill();
		}
		public function castSkill():void{
			
		}
	    public function sendAction():void{

			var p:Player = actorContrl;
			if(p.dead){
			   // waitingAction=false;
			    return;
			}

//			var t:Array = new Array(9);
//			t[0]= DEF.CTS_FT_ACTION;
//			t[1] = p._angle;
//			t[2] = DEF.cInt(p._x);
//			t[3] = DEF.cInt(p._y);
//			
//			t[4] = DEF.cInt(p.sideClipContrl.sideClipAngle);
//			t[5] = DEF.cInt(p.sideClipContrl.speed);
//			t[6] = DEF.cInt(p.up_speed);
//			t[7] = DEF.cInt(p.down_speed);
//			t[8] = p.actionId;
//			t[9] = p.action.getCurentActionCode();
//	
//			mync.call("fight",null,t);
			
			var message:ByteArray=new ByteArray();
			NetTrans.writeByte(message,NetTrans.ACTION_TYPE_FAST);
			NetTrans.writeInt(message,NetTrans.C2S_ACTION_RACE);
			NetTrans.writeByte(message,DEF.CTS_FT_ACTION);
			NetTrans.writeInt(message,p._angle);
			NetTrans.writeShort(message, p._x);
			NetTrans.writeShort(message, p._y);
			
			NetTrans.writeShort(message, p.sideClipContrl.sideClipAngle);
			NetTrans.writeShort(message, DEF.cInt(p.sideClipContrl.speed));
			NetTrans.writeShort(message, DEF.cInt(p.up_speed));
			NetTrans.writeShort(message, DEF.cInt(p.down_speed));
			
			
			NetTrans.writeInt(message,p.actionId);
			NetTrans.writeInt(message,p.action.getCurentActionCode());
			NetTrans.net_send_package(message);

        }
        

        
	    public function sendSkill():void{
			var p:Player = actorContrl;
			if(p.dead){
			    //waitingAction=false;
			    return;
			}
 
			switch(tempSkill){
				case Skill.SKILL_TYPE_STRICK:
//				var t:Array = new Array(5);
//				t[0]= DEF.CTS_FT_SKILL_STRICK;
//				t[1] = p._angle;
//				t[2] = DEF.cInt(p._x);
//				t[3] = DEF.cInt(p._y);
//				t[4] = p.actionId;

				//	mync.call("fight",null,t);
					
					var message:ByteArray=new ByteArray();
					NetTrans.writeByte(message,NetTrans.ACTION_TYPE_FAST);
					NetTrans.writeInt(message,NetTrans.C2S_ACTION_RACE);
					NetTrans.writeByte(message,DEF.CTS_FT_SKILL_STRICK);
					NetTrans.writeInt(message,p._angle);
					NetTrans.writeShort(message, p._x);
					NetTrans.writeShort(message, p._y);
					NetTrans.writeInt(message,p.actionId);
					NetTrans.net_send_package(message);
					
					
	 		        lastInputTime=currentSystemTime;
        	        actorContrl.keyInput.reset();
	 			    ac.spellSkillStrick(p,p._x,p._y,p._angle);
				break;
				default:
//					var t1:Array = new Array(2);
//					t1[0]= DEF.CTS_FT_SKILL;
//					t1[1] = tempSkill;
//					mync.call("fight",null,t1);
					var message:ByteArray=new ByteArray();
					NetTrans.writeByte(message,NetTrans.ACTION_TYPE_FAST);
					NetTrans.writeInt(message,NetTrans.C2S_ACTION_RACE);
					NetTrans.writeByte(message,DEF.CTS_FT_SKILL);
					NetTrans.writeInt(message,tempSkill);
					NetTrans.net_send_package(message);
					
				break;
			}
			tempSkill=-1;
			
        }
 

        public function actionCopy(){
        	for(var i:int=0;i<actions.size();i++){
        		sendActions.push(actions.getObjById(i));
        	}
        	actions.clear();
        	actorContrl.setKeyCode( sendActions);
  	        while(sendActions.length>0){
	        	 sendActions.pop();
	       }      	 
        }

//		public function otherActionsPack(actions:Array):void{
//             ac.checkActions(actions);
//		}
	    public function log(info:String):void{
	    	chat.infoLog(info);
	    } 
	    public var gameOver:Boolean=false;
    	public function  receiveGameScore(message:ByteArray):void{
//        	 if(racingRoom)racingRoom.destroyGame();
//    			 village.enterMatchRoom2(mapid);
             gameOver=true;			
			 _parents.showScore(message);
			 this.stopRacing();
    	}

		public function onError(error:Object):void {
				Alert.show("error"+error.toLocaleString());
				trace(error.description);
		}
		
		public function initWorld():void{
			initMap();
		}
		
        public function initMap():void{
        	mapContrl=new MapContrl(this,bgCanvas,fgCanvas,mapInfo);
        }
        public function initMapOk():void{
			
			var message:ByteArray=new ByteArray();
			NetTrans.writeByte(message,NetTrans.ACTION_TYPE_FAST);
			NetTrans.writeInt(message,NetTrans.C2S_ACTION_RACE);
			NetTrans.writeByte(message,DEF.CTS_FT_LOGIN);
			NetTrans.net_send_package(message);
        	
        }
//        public var loginIsOk:Boolean=false;
//    	public function loginOk(roomInfo:Array):void {
//    		
//    		if(!roomInfo){
//    		 // mync.close();
//    		  return;
//    		}
//    		initPlayers(roomInfo);
//         	//mync.close();
//        }
//    	public function loginError(resultObj:Object):void {
//    		trace("login error");
//         	//mync.close();
//        }
        public function userReady(uid:String):void{
        	
        }
		public var run_id:Number;
		public var isRunning:Boolean=false;
		public var started:Boolean=false;
		

       public var tempActor:Player;


        public function updatePlayers():void{
        	for(var i:int=0;i<players.size();i++){
        		tempActor=(Player)(players.elementAtt(i));
                tempActor.update();
        	}
        }
        public function showPlayers():void{
        	for(var i:int=0;i<players.size();i++){
        		tempActor=(Player)(players.elementAtt(i));
                tempActor.showActor();
        	}
        }
		public function initSelf(x:int,y:int,ang:int,now:int,team:int):void{
			//actorInfo.currentCar=DEF.getTestCar1(new ActorDisplayer(this.acCanvas));
		    actorContrl=new ActorContrl(acCanvas,actorInfo,mapContrl.mapInfo,this);
 		    actorContrl._x=x;
        	actorContrl._y=y;
            actorContrl._viewx=x;
		    actorContrl._viewy=y;
        	actorContrl._angle=ang;
        	//actorContrl.turnActor();
        	actorContrl.setReady(true);
 			actorContrl._parent = this;
			keyContrl=new KeyboardContrl(null);
			keyContrl.setGameCanvasKeyboardEvent(gameCanvas,actorContrl,this.skillBar);
			ac=new ActionChecker(this,this.actorContrl,this.players); 			
			players.put(actorContrl.userInfo.userID,actorContrl);
			skillBar.initSkills(this,actorContrl);
        	mapContrl.actorContrl=actorContrl;
        	actorContrl.mapContrl=mapContrl;
        	actorContrl.refBlood(now);
        	actorContrl.teamId=team;

		}
	  public var totalRaceTime:Number=-1;
      public  var raceStartTime:Number;
        public function setTotalRaceTime(time:Number):void{
        	totalRaceTime=time;
        	raceStartTime=getTimer();
        }
        public var raceTime:Number=0; 
       public var leftTime:Number,currentSystemTime:Number;
	    public function  refreshTimer():void{
        	if(totalRaceTime<0)return;
        	raceTime=currentSystemTime-raceStartTime;
        	leftTime=totalRaceTime-raceTime;
        	if(leftTime<0)leftTime=0;
        	leftTime=(int)(leftTime/1000);
        	timer.setTime(leftTime);
        }

		public function sortDisplayer():void{
//			var num=acCanvas.numChildren;
//			for(var i=0;i<num-1;i++){
//               
//				var obj=acCanvas.getChildAt(i);
//				var obj1=acCanvas.getChildAt(i+1);
//				if(obj.y>obj1.y){
//					acCanvas.setChildIndex(obj,i+1);
//					acCanvas.setChildIndex(obj1,i);
//				}
//			}
		}
		public function addPlayer(id:int,show:String,x:int,y:int,ang:int,ready:Boolean,now:int,team:int,carid:int,partList:Array):void{
			if(id==actorInfo.userID){
				initSelf(x,y,ang,now,team);
			}
			else{
		        var info:UserInfo = new UserInfo(id,show);
		        info.currentCar=new CarInfo(null,ItemLoader.getCar(carid));
				info.currentCar.setPartList(partList);
				var actor:Player=new Player(acCanvas,info,mapContrl.mapInfo,this);
				players.put(info.userID,actor);
			    actor._x=x;
			    actor._y=y;
			    actor._viewx=x;
			    actor._viewy=y;
			    actor._angle=ang;
			    actor.refBlood(now);
			    actor.teamId=team;
			   // actor.turnActor();
			    actor.setReady(ready);
			}
			
		}
	    public function initPlayers(msg:ByteArray):void{
			var size:int=NetTrans.readByte(msg);
	    	for(var i:int=0; i<size;i++){
	    		 
	    		var id:int=NetTrans.readInt(msg);
				var show:String = NetTrans.readString(msg);
	    		var x:int=NetTrans.readShort(msg);
	    		var y:int=NetTrans.readShort(msg);
	    		var angle:int=NetTrans.readInt(msg);
	    		var ready:Boolean=(NetTrans.readByte(msg)==0)?false:true;
	    		var now:int=NetTrans.readInt(msg);
	    		var team:int=NetTrans.readByte(msg);
	    		var carid:int=NetTrans.readInt(msg);
				var s:int=NetTrans.readByte(msg);
	    		var partList:Array=new Array;
	    		
				for(var j:int=0; j<s;j++){
					partList.push(NetTrans.readInt(msg));
				}
	    	    addPlayer(id,show,x,y,angle,ready,now,team,carid,partList);
	    	}

               
               mapContrl.updateMap();
               acCanvas.visible=true;
               bgCanvas.visible=true;
               topCanvas.visible=true;
               fgCanvas.visible=true;
              while(readyList.length>0){
              	var uid=readyList.pop();
              	 
              	var p:Player=(Player)(players.getObjByKey(uid));
              	p.setReady(true);
              }
              makeTeam();
		      applyStartGame(this.userId);
		}
		public function setUserId(uid:int):void
		{
			this.userId = uid;
		}		
		public function makeTeam():void{
			if(mode==0){
			    for(var i:int=0;i<players.size();i++){
	        		tempActor=(Player)(players.elementAtt(i));
	                tempActor.actorDisp.setTeamColor(0xFF5013);
	        	}	
        	}else{
			    for(var i:int=0;i<players.size();i++){
	        		tempActor=(Player)(players.elementAtt(i));
	        		if(tempActor.teamId==actorContrl.teamId)
	        			tempActor.actorDisp.setTeamColor(0x99FF99);
                    else
	               	 	tempActor.actorDisp.setTeamColor(0xFF5013);
	        	}		
        	}
        	this.actorContrl.actorDisp.setTeamColor(0xEEEEFF);
		}
		public function applyStartGame(uid:int):void{
	 
			var message:ByteArray=new ByteArray();
			NetTrans.writeByte(message,NetTrans.ACTION_TYPE_FAST);
			NetTrans.writeInt(message,NetTrans.C2S_ACTION_RACE);
			NetTrans.writeByte(message,DEF.CTS_FT_START);
			NetTrans.net_send_package(message);

		}
    	public function applyStartOk(info:Array):void {
    		if(!info){
    		  //mync.close();
    		  return;
    		}
    		
    		startGame(info[0],info[1]);
         	//mync.close();
        }
        public function startGame(startTime:int,leftTime:int):void{
        	cont.setTime(startTime,leftTime);
        	map.setMap(this);
        }
        private var readyList:Array=new Array;	
        public function otherStartGame(uid:int):void{
        	var p:Player=(Player)(players.getObjByKey(uid));
        	if(p){
        	  p.setReady(true);
        	}
        	else{
        		readyList.push(uid);
        	}
        }
		public var eft:Effect;
        public function addEffect(eft1:Effect):void{
        	this.effects.put(eft1);
        } 
        
        public function checkEffects():void{
        	for(var i:int=0;i<effects.size();i++){
        		eft=(Effect)(effects.getObjById(i));
        		eft.update();
        		
        		if(!eft.valid){
        			effects.remove(i);
        			i--;
        		}
        	}
        }
		public function destroy():void{
		    stopRacing();
	        if(keyContrl) keyContrl.destroy();
			keyContrl=null;
			
			this.mapContrl.destroy();
        	for(var i:int=0;i<players.size();i++){
        		var tempActor:Player=(Player)(players.elementAtt(i));
                tempActor.destroy();
        	}
			players.clear();
			actorContrl=null;
			mapContrl=null;
			gameCanvas.removeAllChildren();

			events.removeEventListener(GameEventDispatcher.ON_ACTION,onAction);
			//mync.close();
			bgCanvas=null;
			acCanvas=null;
			fgCanvas=null;
		}
		//function updateCanvas(e:Event){
			//mapContrl.update();
		//}

	}
}